
package org.sopt.dev.ImgKnight.monitor.gui.builder;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.jboss.netty.channel.Channel;
import org.jfree.chart.JFreeChart;
import org.jfree.experimental.chart.swt.ChartComposite;
import org.sopt.dev.ImgKnight.monitor.Monitor;
import org.sopt.dev.ImgKnight.monitor.chart.AgentChartSet;
import org.sopt.dev.ImgKnight.monitor.chart.FrontierChartSet;
import org.sopt.dev.ImgKnight.monitor.dao.HarvestDAO;
import org.sopt.dev.ImgKnight.monitor.dao.HarvestVO;
import org.sopt.dev.ImgKnight.monitor.dialog.AlertDialog;
import org.sopt.dev.ImgKnight.monitor.nio.Peer;
import org.sopt.dev.ImgKnight.monitor.operation.Operations;
import org.sopt.dev.ImgKnight.monitor.resource.ResourceManager;


public class ContentsBuilder implements Builder {

	public static final int COLUMN_SIZE = 10;
	
	private Monitor monitor = null;
	
	private Peer frontierPeer = null;
	
	private List<Peer> agentPeers = null;
	
	private Tree tree = null;
	
	private Composite condComposite = null;
	
	private StackLayout condStackLayout = null;
	
	private Label numObjectsLabel = null;
	
	private HashMap<String, Composite> condPannel = null;
	
	private FrontierChartSet frontierChart = null;
	
	private HashMap<Channel, AgentChartSet> agentChartMap = null;
	
	private Combo responseForHighPrioUrl = null;
	
	private Combo responseForAllowPattern = null;
	
	private Combo responseForDenyPattern = null;
	
	private Text sleepText = null;
	
	private Text addAllowPatternText = null;
	
	private Text addDenyPatternText = null;
	
	private Text addHighPrioUrlText = null;
	
	private Text rmUrlText = null;
	
	private Table logTable = null;
	
	private Text ipText = null;
	
	private Text portText = null;
	
	private Text idText = null;
	
	private Text passwdText = null;
	
	private Text fetchSizeText = null;
	
	public ContentsBuilder(Monitor monitor, List<Peer> agentPeers) {
		this.monitor = monitor;
		this.frontierPeer = monitor.getFrontierPeer();
		this.agentPeers = agentPeers;
		frontierChart = new FrontierChartSet(monitor);
		agentChartMap = new HashMap<Channel, AgentChartSet>();
		for(int i=0; i<agentPeers.size(); i++)
			agentChartMap.put(agentPeers.get(i).getChannel(), new AgentChartSet(monitor));
	}
	
	@Override
	public void build() {
		SashForm sashForm = new SashForm(monitor.getShell(), SWT.NONE);
		sashForm.setOrientation(SWT.HORIZONTAL);
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL|GridData.FILL_VERTICAL);
		gridData.horizontalSpan = 2;
		sashForm.setLayoutData(gridData);
		createTreeView(sashForm);
		createChartView(sashForm);
		sashForm.setWeights(new int[] { 2, 8 });
		
		numObjectsLabel = new Label(monitor.getShell(), SWT.BORDER);
		numObjectsLabel.setText(Monitor.getResourceString("details.ConnectInfo.text",
				new Object[] { new Integer(1), new Integer(agentPeers.size()) }));
		gridData = new GridData(GridData.FILL_HORIZONTAL|GridData.VERTICAL_ALIGN_FILL);
		gridData.horizontalSpan = 2;
		numObjectsLabel.setLayoutData(gridData);
	}
	
	private void createTreeView(Composite parent) {
		Composite composite = new Composite(parent, SWT.BORDER);
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 1;
		gridLayout.marginHeight = gridLayout.marginWidth = 2;
		gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 2;
		composite.setLayout(gridLayout);
	
		Label treeScopeLabel = new Label(composite, SWT.NONE);
		treeScopeLabel.setText(Monitor.getResourceString("agents.List.text"));
		treeScopeLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL|GridData.VERTICAL_ALIGN_FILL));
		
		tree = new Tree(composite, SWT.BORDER|SWT.V_SCROLL|SWT.H_SCROLL|SWT.SINGLE);
		tree.setLayoutData(new GridData(GridData.FILL_HORIZONTAL|GridData.FILL_VERTICAL));
		tree.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				final TreeItem[] selection = tree.getSelection();
				if (selection != null && selection.length != 0) {
					TreeItem item = selection[0];
					String key = item.getText().substring(item.getText().indexOf("/"));
					condStackLayout.topControl = condPannel.get(key);
					condComposite.layout();
				}
			}
		});
		
		TreeItem frontier = new TreeItem(tree, SWT.NONE);
		frontier.setImage(ResourceManager.loadImage(monitor.getDisplay(), "frontier.png"));
		frontier.setText("Frontier"+monitor.getFrontierPeer().getChannel().getRemoteAddress().toString());
		for(int i=0; i<agentPeers.size(); i++) {
			TreeItem agent = new TreeItem(frontier, SWT.NONE);
			agent.setImage(ResourceManager.loadImage(monitor.getDisplay(), "agent.png"));
			agent.setText("Agnet_"+(i+1)+agentPeers.get(i).getChannel().getRemoteAddress().toString());
		}
	}
	
	private void createChartView(Composite parent) {
		TabFolder folder = new TabFolder(parent, SWT.TOP);
		TabItem conditionTabItem = new TabItem(folder, SWT.NONE);
		conditionTabItem.setImage(ResourceManager.loadImage(monitor.getDisplay(), "condition.png"));
		conditionTabItem.setText(Monitor.getResourceString("tab.First.text"));
		TabItem configureTabItem = new TabItem(folder, SWT.NONE);
		configureTabItem.setImage(ResourceManager.loadImage(monitor.getDisplay(), "settings.png"));
		configureTabItem.setText(Monitor.getResourceString("tab.Second.text"));
		TabItem logTabItem = new TabItem(folder, SWT.NONE);
		logTabItem.setImage(ResourceManager.loadImage(monitor.getDisplay(), "db.png"));
		logTabItem.setText(Monitor.getResourceString("tab.Third.text"));
		
		condPannel = new HashMap<String, Composite>(agentPeers.size()+1);
		condComposite = new Composite(folder, SWT.NONE);
		condStackLayout = new StackLayout();
		condComposite.setLayout(condStackLayout);				
		condPannel.put(frontierPeer.getChannel().getRemoteAddress().toString(), new Composite(condComposite, SWT.NONE));
		for(int i=0; i<agentPeers.size(); i++) {
			Composite comp = new Composite(condComposite, SWT.NONE);
			condPannel.put(agentPeers.get(i).getChannel().getRemoteAddress().toString(), comp);
		}
		createChartItem();
		conditionTabItem.setControl(condComposite);
		configureTabItem.setControl(createSettingsTabItem(folder));
		logTabItem.setControl(createLogTabItem(folder));
		condStackLayout.topControl = condPannel.get(frontierPeer.getChannel().getRemoteAddress().toString());
	}
	
	private void createChartItem() {
		createFrontierChartItem(condPannel.get(frontierPeer.getChannel().getRemoteAddress().toString()));
		for(int i=0; i<agentPeers.size(); i++)
			createAgentChartItem(agentPeers.get(i), 
					condPannel.get(agentPeers.get(i).getChannel().getRemoteAddress().toString()));
	}
	
	private void createFrontierChartItem(Composite parent) {
		parent.setLayout(new FillLayout());
		ScrolledComposite sc = new ScrolledComposite(parent, SWT.V_SCROLL|SWT.H_SCROLL);
		Composite child = new Composite(sc, SWT.NONE);
		GridLayout gridLayout = new GridLayout();
		gridLayout.marginHeight = gridLayout.marginWidth = 2;
		gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 2;
		gridLayout.numColumns = 2;
		child.setLayout(gridLayout);
		
		JFreeChart memoryChart = frontierChart.createMemoryLineChart();
		ChartComposite memoryMeterChart = new ChartComposite(child, SWT.BORDER, memoryChart, true);
		memoryMeterChart.setDisplayToolTips(true);
		memoryMeterChart.setHorizontalAxisTrace(false);
		memoryMeterChart.setVerticalAxisTrace(false);
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = 250;
		gridData.horizontalSpan = 2;
		memoryMeterChart.setLayoutData(gridData);
		
		JFreeChart pushedUrlPieChart = frontierChart.createPushedUrlPieChart();
		JFreeChart pushedUrlLineChart = frontierChart.createPushedUrlLineChart();
		ChartComposite pushedUrlMeterPieChart = new ChartComposite(child, SWT.BORDER, pushedUrlPieChart, true);
		ChartComposite pushedUrlMeterLineChart = new ChartComposite(child, SWT.BORDER, pushedUrlLineChart, true);
		pushedUrlMeterLineChart.setDisplayToolTips(true);
		pushedUrlMeterLineChart.setHorizontalAxisTrace(false);
		pushedUrlMeterLineChart.setVerticalAxisTrace(false);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = 250;
		pushedUrlMeterPieChart.setLayoutData(gridData);
		pushedUrlMeterLineChart.setLayoutData(gridData);
		
		JFreeChart droppedUrlChart = frontierChart.createDroppedUrlPieChart();
		ChartComposite droppedUrlMeterChart = new ChartComposite(child, SWT.BORDER, droppedUrlChart, true);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = 250;
		droppedUrlMeterChart.setLayoutData(gridData);
		
		JFreeChart siteMapMultiLevelChart = frontierChart.createSiteMapMultiLevelLineChart();
		ChartComposite siteMapMultiLevelMeterChart = new ChartComposite(child, SWT.BORDER, siteMapMultiLevelChart, true);
		siteMapMultiLevelMeterChart.setDisplayToolTips(true);
		siteMapMultiLevelMeterChart.setHorizontalAxisTrace(false);
		siteMapMultiLevelMeterChart.setVerticalAxisTrace(false);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = 250;
		siteMapMultiLevelMeterChart.setLayoutData(gridData);
		
		JFreeChart fpDocCurrentChart = frontierChart.createFpDocLineChart();
		ChartComposite fpDocCurrentMeterChart = new ChartComposite(child, SWT.BORDER, fpDocCurrentChart, true);
		fpDocCurrentMeterChart.setDisplayToolTips(true);
		fpDocCurrentMeterChart.setHorizontalAxisTrace(false);
		fpDocCurrentMeterChart.setVerticalAxisTrace(false);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = 250;
		fpDocCurrentMeterChart.setLayoutData(gridData);
		
		JFreeChart traficChart = frontierChart.createTraficLineChart();
		ChartComposite traficMeterChart = new ChartComposite(child, SWT.BORDER, traficChart, true);
		traficMeterChart.setDisplayToolTips(true);
		traficMeterChart.setHorizontalAxisTrace(false);
		traficMeterChart.setVerticalAxisTrace(false);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = 250;
		traficMeterChart.setLayoutData(gridData);
		
		sc.setContent(child);
		sc.setMinSize(parent.getClientArea().width, 1024);
		sc.setExpandHorizontal(true);
		sc.setExpandVertical(true);
	}
	
	private void createAgentChartItem(Peer peer, Composite parent) {
		parent.setLayout(new FillLayout());
		ScrolledComposite sc = new ScrolledComposite(parent, SWT.V_SCROLL|SWT.H_SCROLL);
		Composite child = new Composite(sc, SWT.NONE);
		GridLayout gridLayout = new GridLayout();
		gridLayout.marginHeight = gridLayout.marginWidth = 2;
		gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 2;
		gridLayout.numColumns = 2;
		child.setLayout(gridLayout);
		
		AgentChartSet agentChart = agentChartMap.get(peer.getChannel());
		
		JFreeChart memoryChart = agentChart.createMemoryLineChart();
		ChartComposite memoryMeterChart = new ChartComposite(child, SWT.BORDER, memoryChart, true);
		memoryMeterChart.setDisplayToolTips(true);
		memoryMeterChart.setHorizontalAxisTrace(false);
		memoryMeterChart.setVerticalAxisTrace(false);
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = 250;
		gridData.horizontalSpan = 2;
		memoryMeterChart.setLayoutData(gridData);
		
		JFreeChart fetchedUrlChart = agentChart.createFetchedUrlLineChart();
		ChartComposite fetchedUrlMeterChart = new ChartComposite(child, SWT.BORDER, fetchedUrlChart, true);
		fetchedUrlMeterChart.setDisplayToolTips(true);
		fetchedUrlMeterChart.setHorizontalAxisTrace(false);
		fetchedUrlMeterChart.setVerticalAxisTrace(false);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = 250;
		gridData.horizontalSpan = 2;
		fetchedUrlMeterChart.setLayoutData(gridData);
		
		JFreeChart fetchedUrlChartForRC = agentChart.createFetchedUrlRCPieChart();
		JFreeChart fetchedUrlChartForCD = agentChart.createFetchedUrlCDPieChart();
		ChartComposite fetchedUrlMeterForRC = new ChartComposite(child, SWT.BORDER, fetchedUrlChartForRC, true);
		ChartComposite fetchedUrlMeterForCD = new ChartComposite(child, SWT.BORDER, fetchedUrlChartForCD, true);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = 250;
		fetchedUrlMeterForRC.setLayoutData(gridData);
		fetchedUrlMeterForCD.setLayoutData(gridData);
		
		JFreeChart fetchedResourceChart = agentChart.createFetchedResourceLineChart();
		ChartComposite fetchedResourceMeterChart = new ChartComposite(child, SWT.BORDER, fetchedResourceChart, true);
		fetchedResourceMeterChart.setDisplayToolTips(true);
		fetchedResourceMeterChart.setHorizontalAxisTrace(false);
		fetchedResourceMeterChart.setVerticalAxisTrace(false);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = 250;
		fetchedResourceMeterChart.setLayoutData(gridData);
		
		JFreeChart duplicatedImageChart = agentChart.createDuplicatedImageLineChart();
		ChartComposite duplicatedImageMeterChart = new ChartComposite(child, SWT.BORDER, duplicatedImageChart, true);
		duplicatedImageMeterChart.setDisplayToolTips(true);
		duplicatedImageMeterChart.setHorizontalAxisTrace(false);
		duplicatedImageMeterChart.setVerticalAxisTrace(false);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = 250;
		duplicatedImageMeterChart.setLayoutData(gridData);
		
		JFreeChart fetchedResourceChartForRC = agentChart.createFetchedResourceRCPieChart();
		JFreeChart fetchedResourceChartForCD = agentChart.createFetchedResourceCDPieChart();
		ChartComposite fetchedResourceMeterForRC = new ChartComposite(child, SWT.BORDER, fetchedResourceChartForRC, true);
		ChartComposite fetchedResourceMeterForCD = new ChartComposite(child, SWT.BORDER, fetchedResourceChartForCD, true);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = 250;
		fetchedResourceMeterForRC.setLayoutData(gridData);
		fetchedResourceMeterForCD.setLayoutData(gridData);
		
		JFreeChart seenImageChart = agentChart.createSeenImageLineChart();
		ChartComposite seenImageMeterChart = new ChartComposite(child, SWT.BORDER, seenImageChart, true);
		seenImageMeterChart.setDisplayToolTips(true);
		seenImageMeterChart.setHorizontalAxisTrace(false);
		seenImageMeterChart.setVerticalAxisTrace(false);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = 250;
		seenImageMeterChart.setLayoutData(gridData);
		
		JFreeChart traficChart = agentChart.createTraficLineChart();
		ChartComposite traficMeterChart = new ChartComposite(child, SWT.BORDER, traficChart, true);
		traficMeterChart.setDisplayToolTips(true);
		traficMeterChart.setHorizontalAxisTrace(false);
		traficMeterChart.setVerticalAxisTrace(false);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = 250;
		traficMeterChart.setLayoutData(gridData);
		
		sc.setContent(child);
		sc.setMinSize(parent.getClientArea().width, 1537);
		sc.setExpandHorizontal(true);
		sc.setExpandVertical(true);
	}
	
	private Composite createSettingsTabItem(TabFolder folder) {
		Composite settingsCompoiste = new Composite(folder, SWT.NONE);
		GridLayout gridLayout = new GridLayout();
		gridLayout.marginHeight = gridLayout.marginWidth = 2;
		gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 2;
		gridLayout.numColumns = 1;
		settingsCompoiste.setLayout(gridLayout);
		
		Group requestForSettingsArea = new Group(settingsCompoiste, SWT.SHADOW_NONE);
		requestForSettingsArea.setText("Request for frontier settings");
		gridLayout = new GridLayout();
		gridLayout.numColumns = 3;
		requestForSettingsArea.setLayout(gridLayout);		
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		requestForSettingsArea.setLayoutData(gridData);
		
		new Label(requestForSettingsArea, SWT.PUSH).setText("High-prioriry URL:");
		Button highPrioUrlBtn = new Button(requestForSettingsArea, SWT.PUSH);
		highPrioUrlBtn.setText("Send");
		highPrioUrlBtn.addSelectionListener(new SelectionAdapter () {
			public void widgetSelected(SelectionEvent event) {
				Operations.infoHighPrioUrl(monitor.getFrontierPeer().getChannel());
			}
		});
		responseForHighPrioUrl = new Combo(requestForSettingsArea, SWT.DROP_DOWN);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.horizontalIndent = 10;
		responseForHighPrioUrl.setText("Result: None");
		responseForHighPrioUrl.setLayoutData(gridData);
		
		new Label(requestForSettingsArea, SWT.PUSH).setText("Allow patterns:");
		Button allowPattenBtn = new Button(requestForSettingsArea, SWT.PUSH);
		allowPattenBtn.setText("Send");
		allowPattenBtn.addSelectionListener(new SelectionAdapter () {
			public void widgetSelected(SelectionEvent event) {
				Operations.infoAllowPattern(monitor.getFrontierPeer().getChannel());
			}
		});
		responseForAllowPattern = new Combo(requestForSettingsArea, SWT.DROP_DOWN);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.horizontalIndent = 10;
		responseForAllowPattern.setText("Result: None");
		responseForAllowPattern.setLayoutData(gridData);
		
		new Label(requestForSettingsArea, SWT.PUSH).setText("Deny patterns:");
		Button denyPatternBtn = new Button(requestForSettingsArea, SWT.PUSH);
		denyPatternBtn.setText("Send");
		denyPatternBtn.addSelectionListener(new SelectionAdapter () {
			public void widgetSelected(SelectionEvent event) {
				Operations.infoDenyPattern(monitor.getFrontierPeer().getChannel());
			}
		});
		responseForDenyPattern = new Combo(requestForSettingsArea, SWT.DROP_DOWN);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.horizontalIndent = 10;
		responseForDenyPattern.setText("Result: None");
		responseForDenyPattern.setLayoutData(gridData);
		
		Group requestForSleepArea = new Group(settingsCompoiste, SWT.SHADOW_NONE);
		requestForSleepArea.setText("Sleep");
		gridLayout = new GridLayout();
		gridLayout.numColumns = 4;
		requestForSleepArea.setLayout(gridLayout);		
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.verticalIndent = 10;
		requestForSleepArea.setLayoutData(gridData);
		
		new Label(requestForSleepArea, SWT.PUSH).setText("Frontier sleep for ");
		sleepText = new Text(requestForSleepArea, SWT.BORDER|SWT.RIGHT);
		gridData = new GridData();
		gridData.widthHint = 30;
		sleepText.setLayoutData(gridData);
		new Label(requestForSleepArea, SWT.PUSH).setText(" second. ");
		Button sleepBtn = new Button(requestForSleepArea, SWT.PUSH);
		sleepBtn.setText("Commit");
		sleepBtn.addSelectionListener(new SelectionAdapter () {
			public void widgetSelected(SelectionEvent event) {
				int millisec = 0;
				try { millisec = Integer.parseInt(sleepText.getText()); }
				catch(NumberFormatException ignore) { /**/ }
				millisec = millisec * 1000;
				if( millisec == 0 ) {
					AlertDialog.alert(monitor.getShell(), "Invalid Parameter", "Input Number");
					return;
				}
				Operations.sleep(monitor.getFrontierPeer().getChannel(), millisec);
			}
		});
		
		Group requestForAddArea = new Group(settingsCompoiste, SWT.SHADOW_NONE);
		requestForAddArea.setText("Add keyword (Each keyword separated by a space)");
		gridLayout = new GridLayout();
		gridLayout.numColumns = 3;
		requestForAddArea.setLayout(gridLayout);		
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.verticalIndent = 10;
		requestForAddArea.setLayoutData(gridData);
		
		new Label(requestForAddArea, SWT.PUSH).setText("High-prioriry URL:");
		addHighPrioUrlText = new Text(requestForAddArea, SWT.BORDER);
		gridData = new GridData();
		gridData.widthHint = 400;
		addHighPrioUrlText.setLayoutData(gridData);
		Button addHighPrioUrlBtn = new Button(requestForAddArea, SWT.PUSH);
		addHighPrioUrlBtn.setText("Commit");
		addHighPrioUrlBtn.addSelectionListener(new SelectionAdapter () {
			public void widgetSelected(SelectionEvent event) {
				String urlString = addHighPrioUrlText.getText();
				if( !urlString.startsWith("http://") )
					urlString = "http://"+urlString;
				try {
					new URL(urlString);
				} catch (MalformedURLException e) {
					AlertDialog.alert(monitor.getShell(), "Invalid Parameter", e.getMessage());
					return;
				}
				Operations.addHighPrioUrl(monitor.getFrontierPeer().getChannel(), urlString);
			}
		});
		
		new Label(requestForAddArea, SWT.PUSH).setText("Allow pattern:");
		addAllowPatternText = new Text(requestForAddArea, SWT.BORDER);
		gridData = new GridData();
		gridData.widthHint = 400;
		addAllowPatternText.setLayoutData(gridData);
		Button addAllowPatternBtn = new Button(requestForAddArea, SWT.PUSH);
		addAllowPatternBtn.setText("Commit");
		addAllowPatternBtn.addSelectionListener(new SelectionAdapter () {
			public void widgetSelected(SelectionEvent event) {
				Operations.addAllowPattern(monitor.getFrontierPeer().getChannel(), addAllowPatternText.getText());
			}
		});
		
		new Label(requestForAddArea, SWT.PUSH).setText("Deny pattern:");
		addDenyPatternText = new Text(requestForAddArea, SWT.BORDER);
		gridData = new GridData();
		gridData.widthHint = 400;
		addDenyPatternText.setLayoutData(gridData);
		Button addDenyPatternBtn = new Button(requestForAddArea, SWT.PUSH);
		addDenyPatternBtn.setText("Commit");
		addDenyPatternBtn.addSelectionListener(new SelectionAdapter () {
			public void widgetSelected(SelectionEvent event) {
				Operations.addDenyPattern(monitor.getFrontierPeer().getChannel(), addDenyPatternText.getText());
			}
		});
		
		Group requestForRmArea = new Group(settingsCompoiste, SWT.SHADOW_NONE);
		requestForRmArea.setText("Remove keyword (Each keyword separated by a space)");
		gridLayout = new GridLayout();
		gridLayout.numColumns = 4;
		requestForRmArea.setLayout(gridLayout);		
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.verticalIndent = 10;
		requestForRmArea.setLayoutData(gridData);
		
		new Label(requestForRmArea, SWT.PUSH).setText("Host URL:");
		rmUrlText = new Text(requestForRmArea, SWT.BORDER);
		gridData = new GridData();
		gridData.widthHint = 400;
		rmUrlText.setLayoutData(gridData);
		Button rmUrlBtn = new Button(requestForRmArea, SWT.PUSH);
		rmUrlBtn.setText("Commit");
		rmUrlBtn.addSelectionListener(new SelectionAdapter () {
			public void widgetSelected(SelectionEvent event) {
				String urlString = rmUrlText.getText();
				if( !urlString.startsWith("http://") )
					urlString = "http://"+urlString;
				try {
					new URL(urlString);
				} catch (MalformedURLException e) {
					AlertDialog.alert(monitor.getShell(), "Invalid Parameter", e.getMessage());
					return;
				}
				Operations.removeUrl(monitor.getFrontierPeer().getChannel(), urlString);
			}
		});
		return settingsCompoiste;
	}
	
	private Composite createLogTabItem(TabFolder folder) {
		Composite dbComposite = new Composite(folder, SWT.NONE);
		GridLayout gridLayout = new GridLayout();
		gridLayout.marginHeight = gridLayout.marginWidth = 2;
		gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 2;
		gridLayout.numColumns = 1;
		dbComposite.setLayout(gridLayout);
		
		Group operationArea = new Group(dbComposite, SWT.SHADOW_NONE);
		operationArea.setText("Connect to MySQL Server Instance");
		gridLayout = new GridLayout();
		gridLayout.numColumns = 8;
		operationArea.setLayout(gridLayout);		
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		operationArea.setLayoutData(gridData);

		new Label(operationArea, SWT.PUSH).setText("Server Host:");
		ipText = new Text(operationArea, SWT.BORDER);
		gridData = new GridData();
		gridData.widthHint = 100;
		ipText.setLayoutData(gridData);
		
		new Label(operationArea, SWT.PUSH).setText(" Port:");
		portText = new Text(operationArea, SWT.BORDER);
		portText.setText("3306");
		gridData = new GridData();
		gridData.widthHint = 50;
		portText.setLayoutData(gridData);
		
		new Label(operationArea, SWT.PUSH).setText(" Username:");
		idText = new Text(operationArea, SWT.BORDER);
		gridData = new GridData();
		gridData.widthHint = 80;
		idText.setLayoutData(gridData);
		
		new Label(operationArea, SWT.PUSH).setText(" Password:");
		passwdText = new Text(operationArea, SWT.BORDER|SWT.PASSWORD);
		gridData = new GridData();
		gridData.widthHint = 80;
		passwdText.setLayoutData(gridData);
		
		new Label(operationArea, SWT.PUSH).setText("Recent Log:");
		fetchSizeText = new Text(operationArea, SWT.BORDER|SWT.RIGHT);
		fetchSizeText.setText("100");
		gridData = new GridData();
		gridData.widthHint = 80;
		fetchSizeText.setLayoutData(gridData);
		
		Button okBtn = new Button(operationArea, SWT.PUSH);
		okBtn.setText("OK");
		gridData = new GridData();
		gridData.widthHint = 50;
		okBtn.setLayoutData(gridData);
		okBtn.addSelectionListener(new SelectionAdapter () {
			public void widgetSelected(SelectionEvent event) {
				HarvestDAO harvestDAO = new HarvestDAO(monitor, 
						ipText.getText(), portText.getText(), idText.getText(), passwdText.getText());
				int size = 0;
				try { size = Integer.parseInt(fetchSizeText.getText()); } 
				catch (Exception ignore) { /**/ }
				List<HarvestVO> recentLog = harvestDAO.getRecentLog(size);
				if( recentLog != null ) {
					logTable.removeAll();
					for(HarvestVO vo : recentLog) {
						TableItem item = new TableItem(logTable, SWT.NONE);
						for(int i=0; i<COLUMN_SIZE; i++)
							item.setText(i, vo.getValue(i));
					}
				}
			}
		});
		
		logTable = new Table(dbComposite, SWT.BORDER|SWT.FULL_SELECTION|SWT.SINGLE);
		gridData = new GridData(GridData.FILL_HORIZONTAL|GridData.FILL_VERTICAL);
		gridData.verticalIndent = 5;
		logTable.setLayoutData(gridData);
		logTable.setHeaderVisible(true);
		logTable.setLinesVisible(true);
		
		TableColumn idColumn = new TableColumn(logTable, SWT.LEFT);
		idColumn.setText("id");
		idColumn.pack();
		TableColumn siteColumn = new TableColumn(logTable, SWT.LEFT);
		siteColumn.setText("Site");
		siteColumn.pack();
		TableColumn pageUrlColumn = new TableColumn(logTable, SWT.LEFT);
		pageUrlColumn.setText("Page URL");
		pageUrlColumn.pack();
		TableColumn imgUrlColumn = new TableColumn(logTable, SWT.LEFT);
		imgUrlColumn.setText("Image URL");
		imgUrlColumn.pack();
		TableColumn fileNameColumn = new TableColumn(logTable, SWT.LEFT);
		fileNameColumn.setText("File Path");
		fileNameColumn.pack();
		TableColumn sizeColumn = new TableColumn(logTable, SWT.LEFT);
		sizeColumn.setText("Size");
		sizeColumn.pack();
		TableColumn statusColumn = new TableColumn(logTable, SWT.LEFT);
		statusColumn.setText("Status");
		statusColumn.pack();
		TableColumn countryCodeColumn = new TableColumn(logTable, SWT.LEFT);
		countryCodeColumn.setText("Country Code");
		countryCodeColumn.pack();
		TableColumn countryNameColumn = new TableColumn(logTable, SWT.LEFT);
		countryNameColumn.setText("Country Name");
		countryNameColumn.pack();
		TableColumn timestampColumn = new TableColumn(logTable, SWT.LEFT);
		timestampColumn.setText("Timestamp");
		timestampColumn.pack();
		logTable.addListener(SWT.MouseDown, new Listener() {
			public void handleEvent(Event event) {
				Point pt = new Point(event.x, event.y);
				TableItem item = logTable.getItem(pt);
				if( item == null )
					return;
				for(int i=1; i<4; i++) {
					Rectangle rect = item.getBounds(i);
					if( rect.contains(pt) ) {
						String system = System.getProperty("os.name");
						if( system.contains("Windows") ) {
							try {
								Runtime.getRuntime().exec("C:\\Program Files\\Internet Explorer\\iexplore "+item.getText(i));
							} catch (IOException ignore) {}
						}
						else if( system.contains("Linux") ){
							/* TODO */
						}
						break;
					}
				}
			}
		});
		return dbComposite;
	}

	public boolean isFrontierPeer(Channel channel) {
		return frontierPeer.getChannel().equals(channel);
	}
	
	public FrontierChartSet getFrontierChartSet() {
		return frontierChart;
	}

	public String getCurrentSelectedPeerIpAddress() {
		String peerAddress = null;
		TreeItem[] selection = tree.getSelection();
		if (selection != null && selection.length != 0) {
			TreeItem item = selection[0];
			peerAddress = item.getText().substring(item.getText().indexOf("/"));
		}
		return peerAddress;
	}
	
	public AgentChartSet getAgentChartSet(Channel peer) {
		return agentChartMap.get(peer);
	}

	public void setResponseForHighPrioUrlText(final String response) {
		monitor.getDisplay().asyncExec(new Runnable() {
			public void run() {
				responseForHighPrioUrl.removeAll();
				StringTokenizer tokenizer = new StringTokenizer(response);
				responseForHighPrioUrl.setText("Result: "+tokenizer.countTokens());
				while( tokenizer.hasMoreTokens() ) {
					responseForHighPrioUrl.add(tokenizer.nextToken());
				}
			}
		});
	}

	public void setResponseForAllowPatternText(final String response) {
		monitor.getDisplay().asyncExec(new Runnable() {
			public void run() {
				responseForAllowPattern.removeAll();
				StringTokenizer tokenizer = new StringTokenizer(response);
				responseForAllowPattern.setText("Result: "+tokenizer.countTokens());
				while( tokenizer.hasMoreTokens() ) {
					responseForAllowPattern.add(tokenizer.nextToken());
				}
			}
		});
	}
	
	public void setResponseForDenyPatternText(final String response) {
		monitor.getDisplay().asyncExec(new Runnable() {
			public void run() {
				responseForDenyPattern.removeAll();
				StringTokenizer tokenizer = new StringTokenizer(response);
				responseForDenyPattern.setText("Result: "+tokenizer.countTokens());
				while( tokenizer.hasMoreTokens() ) {
					responseForDenyPattern.add(tokenizer.nextToken());
				}
			}
		});
	}
	
}
